<script type="text/javascript">
    $(document).ready(function () {
    });

    let tableOption = {
        destroy: true,
        processing: true,
        searching: false,  // will initiating a request to the background
        ordering: false,   // will initiating a request to the background
        orderClasses: true,
        clickToSelect: true,

        compact: true,
        hover: true,
        stripe: true,

        serverSide: true,
        paging: true,
        pageLength: 25,
        lengthMenu: [10, 25, 50, 100],
        pagingType: "full_numbers",
        scrollX: true,
        rowCallback: function (row, data, index) {
            if (index % 2 === 0) {
                $(row).css("color", "black");
                $(row).css("background", "#FFEFD5");
            }
        },
        language: {
            "sProcessing": "处理中...",
            "sLengthMenu": "显示 _MENU_ 项结果",
            "sZeroRecords": "没有匹配结果",
            "sInfo": "显示第 _START_ 至 _END_ 项结果，共 _TOTAL_ 项",
            "sInfoEmpty": "显示第 0 至 0 项结果，共 0 项",
            "sInfoFiltered": "(由 _MAX_ 项结果过滤)",
            "sInfoPostFix": "",
            "sSearch": "搜索:",
            "sUrl": "",
            "sEmptyTable": "表中数据为空",
            "sLoadingRecords": "载入中...",
            "sInfoThousands": ",",
            "oPaginate": {
                "sFirst": "首页",
                "sPrevious": "上页",
                "sNext": "下页",
                "sLast": "末页"
            },
            "oAria": {
                "sSortAscending": ": 以升序排列此列",
                "sSortDescending": ": 以降序排列此列"
            }
        }
    };

    $.fn.dataTable.render.ellipsis = function (cutoff) {
        return function (data, type, row) {
            if (type === 'display') {
                let str = data.toString(); // cast numbers

                return str.length < cutoff ? str : str.substr(0, cutoff - 1) + '&#8230;';
            }

            return data;
        };
    };

    Date.prototype.format = function (format) {
        let date = {
            "M+": this.getMonth() + 1,
            "d+": this.getDate(),
            "h+": this.getHours(),
            "m+": this.getMinutes(),
            "s+": this.getSeconds(),
            "q+": Math.floor((this.getMonth() + 3) / 3),
            "S+": this.getMilliseconds()
        };
        if (/(y+)/i.test(format)) {
            format = format.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length));
        }
        for (let k in date) {
            if (new RegExp("(" + k + ")").test(format)) {
                format = format.replace(RegExp.$1, RegExp.$1.length == 1
                    ? date[k] : ("00" + date[k]).substr(("" + date[k]).length));
            }
        }
        return format;
    };
</script>
<script>
    $(function () {
        //Initialize Select2 Elements
        $('.select2').select2();

        //Date picker
        $('.date-picker').datepicker({
            autoclose: true,
            todayHighlight: true
        });
    });

    let jobCtlTable = null;
    let jobDtlTable = null;
    let execTimes = [
        {"key": 0, "value": "单次执行"},
        {"key": 1, "value": "多次执行"}
    ];
    let execDay = [
        {"key": 0, "value": "自然日"},
        {"key": 1, "value": "工作日"},
        {"key": 2, "value": "节假日"}
    ];
    let jobStatus = [
        {"key": 0, "value": "执行成功", "class": "label label-success"},
        {"key": 1, "value": "执行中", "class": "label label-warning"},
        {"key": 2, "value": "执行失败", "class": "label label-danger"},
        {"key": 9, "value": "初始化", "class": "label label-primary"}
    ];
    let valid = [
        {"key": 0, "value": "启用", "class": "fa fa-check label label-success"},
        {"key": 1, "value": "停用", "class": "fa fa-close label label-danger"}
    ];

    let getExecTimesValue = key => getValue(execTimes, key);
    let getExecDayValue = key => getValue(execDay, key);
    let getValidValue = key => getValue(valid, key);
    let getJobStatusValue = key => getValue(jobStatus, key);
    let getExecTimesValues = keys => getValues(execTimes, keys);
    let getExecDayValues = keys => getValues(execDay, keys);
    let getValidValues = keys => getValues(valid, keys);
    let getJobStatusValues = keys => getValues(jobStatus, keys);

    let getJobStatusInfo = key => getValueInfo(jobStatus, key);
    let getValidInfo = key => getValueInfo(valid, key);

    let getExecTimesKey = value => getKey(execTimes, value);
    let getExecDayKey = value => getKey(execDay, value);
    let getJobStatusKey = value => getKey(jobStatus, value);
    let getValidKey = value => getKey(valid, value);
    let getExecTimesKeys = values => getKeys(execTimes, values);
    let getExecDayKeys = values => getKeys(execDay, values);
    let getJobStatusKeys = values => getKeys(jobStatus, values);

    function getKey(map, value) {
        let key = 0;
        map.some(function (item) {
            if (item.value === value) {
                key = item.key;
                return true;
            }
        });
        return key;
    }

    function getKeys(map, values) {
        let keys = [];
        keys.forEach(function (value) {
            keys.push(getKey(map, value));
        });
        return keys;
    }

    function getValue(map, key) {
        if (typeof(key) === "string") {
            return key;
        }

        let value = "未知";
        map.some(function (item) {
            if (item.key === key) {
                value = item.value;
                return true;
            }
        });
        return value;
    }

    function getValues(map, keys) {
        let values = [];
        keys.forEach(function (key) {
            values.push(getValue(map, key));
        });
        return values;
    }

    function getValueInfo(map, key) {
        let values = {"value": "未知"};
        map.some(function (item) {
            if (item.key === key) {
                values["value"] = item.value;
                values["class"] = item.class;
                return true;
            }
        });
        return values;
    }

    function getValueShow(key, value) {
        if (key === "execDay") {
            return getExecDayValue(value)
        } else if (key === "execTimes") {
            return getExecTimesValue(value)
        } else if (key === "jobStatus") {
            return getJobStatusValue(value)
        }
        return value;
    }

    let fields = {};
    let fieldMap = {
        id: "编号",
        jobDate: "任务日期",
        jobId: "任务编号",
        jobName: "任务名称",
        command: "任务命令",
        execTimes: "执行方式",
        dependJobId: "依赖任务",
        dependCustom: "自定义",
        cron: "定时配置",
        timeout: "超时时间(s)",
        maxFailures: "剩余重试次数",
        execDay: "执行日期",
        valid: "启用标志",
        jobStatus: "任务状态",
        jobStatusDesc: "任务描述",
        createTime: "创建时间",
        updateTime: "更新时间",
    };

    for (let key of Object.keys(fieldMap)) {
        fields[key] = "";
    }

    let vmCtl = new Vue({
        el: '#mainTable',
        data: {
            searchArea: {
                jobId: "",
                execTimes: getExecTimesValues([0, 1]),
                execDay: getExecDayValues([0, 1, 2]),
                valid: getValidValues([0,1]),
            },
            selectList: {
                execTimes: execTimes,
                execDay: execDay,
                valid: valid
            },
            addJobCtlTable: Object.assign({}, fields),
            editJobCtlTable: Object.assign({}, fields),
            deleteJobCtlTable: {
                jobId: "",
                jobName: ""
            },
            runJobCtlTable: {
                jobId: "",
                jobName: ""
            }
        },
        watch: {
            "searchArea.execTimes": function (val, oval) {
                $('#execTimesSelect').val(val);
                $("#execTimesSelect").select2();
            },
            "searchArea.execDay": function (val, oval) {
                $('#execDaySelect').val(val);
                $("#execDaySelect").select2();
            },
            "searchArea.valid": function (val, oval) {
                $('#validSelect').val(val);
                $("#validSelect").select2();
            },
            "addJobCtlTable.execTimes": val => {
                $("#addJobCtlTableExecTimes").val(val);
                $("#addJobCtlTableExecTimes").select2();
            },
            "addJobCtlTable.execDay": val => {
                $("#addJobCtlTableExecDay").val(val);
                $("#addJobCtlTableExecDay").select2();
            },
            "addJobCtlTable.valid": val => {
                $("#addJobCtlTableValid").val(val);
                $("#addJobCtlTableValid").select2();
            },
            "editJobCtlTable.execTimes": val => {
                $("#editJobCtlTableExecTimes").val(val);
                $("#editJobCtlTableExecTimes").select2();
            },
            "editJobCtlTable.execDay": val => {
                $("#editJobCtlTableExecDay").val(val);
                $("#editJobCtlTableExecDay").select2();
            },
            "editJobCtlTable.valid": val => {
                $("#editJobCtlTableValid").val(val);
                $("#editJobCtlTableValid").select2();
            },
        }
    });

    let vmDtl = new Vue({
        el: '#dtlTable',
        data: {
            searchArea: {
                jobDate: new Date().format('MM/dd/yyyy'),
                jobId: "",
                jobStatus: getJobStatusValues([0,1,2])
            },
            selectList: {
                jobStatus: jobStatus
            },
        },
        watch: {
            "searchArea.jobDate": val => $('#jobDateInput').datepicker('setDate', val),
            "searchArea.jobStatus": function (val, oval) {
                $('#jobStatusSelect').val(val);
                $("#jobStatusSelect").select2();
            },
        }
    });

    $(document).ready(function () {
        $('.select2').on('change', function (e) {
            //console.log(e.target.id, "change to", e.target.value);
            if (e.target.id === "addJobCtlTableExecTimes") {
                vmCtl.addJobCtlTable.execTimes = e.target.value;
            } else if (e.target.id === "addJobCtlTableExecDay") {
                vmCtl.addJobCtlTable.execDay = e.target.value;
            } else if (e.target.id === "addJobCtlTableValid") {
                vmCtl.addJobCtlTable.valid = e.target.value;
            } else if (e.target.id === "editJobCtlTableExecTimes") {
                vmCtl.editJobCtlTable.execTimes = e.target.value;
            } else if (e.target.id === "editJobCtlTableExecDay") {
                vmCtl.editJobCtlTable.execDay = e.target.value;
            } else if (e.target.id === "editJobCtlTableValid") {
                vmCtl.editJobCtlTable.valid = e.target.value;
            } else if (e.target.id === "execTimesSelect") {
                vmCtl.searchArea.execTimes = $('#execTimesSelect').select2('val');
            } else if (e.target.id === "execDaySelect") {
                vmCtl.searchArea.execDay = $('#execDaySelect').select2('val');
            } else if (e.target.id === "validSelect") {
                vmCtl.searchArea.valid = $('#validSelect').select2('val');
            } else if (e.target.id === "jobStatusSelect") {
                vmDtl.searchArea.jobStatus = $('#jobStatusSelect').select2('val');
            }
        });

        $('.date-picker').on('change', function (e) {
            if (e.target.id === "jobDateInput") {
                vmDtl.searchArea.jobDate = e.target.value;
            }
        });

        jobCtlQuery();
        jobDtlQuery();
    });

    function jobCtlReset() {
        vmCtl.searchArea.execTimes = [];
        vmCtl.searchArea.execDay = [];
        vmCtl.searchArea.valid = [];
    }

    function jobCtlQuery() {
        let queryParams = {jobId: "", execTimes: [], execDay: [], valid: []};

        queryParams.jobId = vmCtl.searchArea.jobId;

        vmCtl.searchArea.execTimes.forEach(function (item) {
            queryParams.execTimes.push(getExecTimesKey(item));
        });

        vmCtl.searchArea.execDay.forEach(function (item) {
            queryParams.execDay.push(getExecDayKey(item));
        });

        vmCtl.searchArea.valid.forEach(function (item) {
            queryParams.valid.push(getValidKey(item));
        });

        //console.log("query:", queryParams);

        jobCtlTable = $('#jobCtlTable').DataTable(Object.assign({
            "ajax": {
                "url": '{[{urlfor "JobCtlController.Get"}]}',
                "type": "GET",
                "data": queryParams,
                "dataSrc": "data",
            },
            columns: [
                {"data": "number", "sDefaultContent": "-"},
                {"data": "jobId", "render": $.fn.dataTable.render.text()},
                {"data": "jobName", "render": $.fn.dataTable.render.ellipsis(20)},
                {"data": "command", "render": $.fn.dataTable.render.ellipsis(20)},
                {"data": "cron", "render": $.fn.dataTable.render.text()},
                {
                    "data": "execDay",
                    "render": data => getExecDayValue(data)
                },
                {
                    "data": "execTimes",
                    "render": data => getExecTimesValue(data)
                },
                {"data": "timeout", "render": $.fn.dataTable.render.text()},
                {"data": "maxFailures", "render": $.fn.dataTable.render.text()},
                {"data": "dependJobId", "render": $.fn.dataTable.render.text()},
                {"data": "dependCustom", "render": $.fn.dataTable.render.ellipsis(10)},
                {
                    "data": "valid",
                    "render": function (data) {
                        let values = getValidInfo(data);

                        return '<i class="' + values.class + '">' + values.value + '</i>';
                    }
                },
                {
                    "data": "action",
                    "render": function (data, type, row, meta) {
                        return '<i class="fa fa-pencil" style="font-size:20px;cursor:pointer" data-toggle="modal" data-target="#edit-jobCtlTable"></i>\n' +
                            '<i class="fa fa-search-plus" style="font-size:20px;cursor:pointer" onclick="jobCtlDetail('+ meta.row + ')"></i>\n' +
                            '<i class="fa fa-trash" style="font-size:20px;cursor:pointer" data-toggle="modal" data-target="#delete-jobCtlTable"></i>\n' +
                            '<i class="fa fa-play" style="font-size:20px;cursor:pointer" data-toggle="modal" data-target="#run-jobCtlTable"></i>';
                    }
                },
            ],
            columnDefs: [
                {targets: 0, visible: false}
            ],
            initComplete: function () {
                //console.log("datatable init success");
            },
            fixedColumns: {
                leftColumns: 3,
                rightColumns: 0
            }
        }, tableOption));

        $('#jobCtlTable').on('click', 'tr', function (e) {
            //$(this).css("background", "#E5E5E5");
            jobCtlTableEditInit(jobCtlTable.row(this).data());
        });
    }

    function jobDtlReset() {
        vmDtl.searchArea.jobId = "";
        vmDtl.searchArea.jobStatus = [];
    }

    function jobDtlQuery() {
        let queryParams = {jobDate: new Date().format('yyyy-MM-dd'), jobId: vmDtl.searchArea.jobId, jobStatus: []};

        if (vmDtl.searchArea.jobDate.length > 0) {
            queryParams.jobDate = new Date(new Date(vmDtl.searchArea.jobDate).getTime()).format('yyyy-MM-dd');
        }

        vmDtl.searchArea.jobStatus.forEach(function (item) {
            queryParams.jobStatus.push(getJobStatusKey(item));
        });

        //console.log("query:", queryParams);

        jobDtlTable = $('#jobDtlTable').DataTable(Object.assign({
            "ajax": {
                "url": '{[{urlfor "JobDtlController.Get"}]}',
                "type": "GET",
                "data": queryParams,
                "dataSrc": "data",
            },
            columns: [
                {"data": "number", "sDefaultContent": "-"},
                {"data": "jobDate", "render": $.fn.dataTable.render.text()},
                {"data": "jobId", "render": $.fn.dataTable.render.text()},
                {"data": "jobName", "render": $.fn.dataTable.render.ellipsis(10)},
                {"data": "command", "render": $.fn.dataTable.render.ellipsis(10)},
                {"data": "cron", "render": $.fn.dataTable.render.text()},
                {"data": "dependJobId", "render": $.fn.dataTable.render.text()},
                {"data": "dependCustom", "render": $.fn.dataTable.render.ellipsis(10)},
                {
                    "data": "jobStatus",
                    "render": function (data) {
                        let values = getJobStatusInfo(data);

                        return '<span class="' + values.class + '">' + values.value + '</span>';
                    }
                },
                {"data": "createTime", "render": $.fn.dataTable.render.text()},
                {"data": "updateTime", "render": $.fn.dataTable.render.text()},
                {
                    "data": "action",
                    "render": function (data, type, row, meta) {
                        return '<i class="fa fa-search-plus" style="font-size:20px;cursor:pointer" onclick="jobDtlDetail(' + meta.row + ')"></i>';

                    }
                },
            ],
            columnDefs: [
                {targets: 0, visible: false}
            ],
            initComplete: function () {
                //console.log("datatable init success");
            },
            fixedColumns: {
                leftColumns: 3,
                rightColumns: 0
            }
        }, tableOption));
    }

    function jobCtlTableEditInit(row) {
        vmCtl.editJobCtlTable.jobId = row.jobId;
        vmCtl.editJobCtlTable.jobName = row.jobName;
        vmCtl.editJobCtlTable.command = row.command;
        vmCtl.editJobCtlTable.cron = row.cron;
        vmCtl.editJobCtlTable.execDay = getExecDayValue(row.execDay);
        vmCtl.editJobCtlTable.execTimes = getExecTimesValue(row.execTimes);
        vmCtl.editJobCtlTable.timeout = row.timeout;
        vmCtl.editJobCtlTable.maxFailures = row.maxFailures;
        vmCtl.editJobCtlTable.dependJobId = row.dependJobId;
        vmCtl.editJobCtlTable.dependCustom = row.dependCustom;
        vmCtl.editJobCtlTable.valid = getValidValue(row.valid);

        $("#editJobCtlTableExecTimes").val(vmCtl.editJobCtlTable.execTimes);
        $("#editJobCtlTableExecTimes").select2();
        $("#editJobCtlTableExecDay").val(vmCtl.editJobCtlTable.execDay);
        $("#editJobCtlTableExecDay").select2();
        $("#editJobCtlTableValid").val(vmCtl.editJobCtlTable.valid);
        $("#editJobCtlTableValid").select2();

        vmCtl.deleteJobCtlTable.jobId = row.jobId;
        vmCtl.deleteJobCtlTable.jobName = row.jobName;
        vmCtl.runJobCtlTable.jobId = row.jobId;
        vmCtl.runJobCtlTable.jobName = row.jobName;
    }

    function jobCtlTableAdd() {
        let addParams = Object.assign({}, vmCtl.addJobCtlTable);

        addParams.execDay = getExecDayKey(addParams.execDay);
        addParams.execTimes = getExecTimesKey(addParams.execTimes);
        addParams.valid = getExecTimesKey(addParams.valid);

        //console.log("add:", addParams);

        Vue.http.post('{[{urlfor "JobCtlController.Post"}]}', addParams).then(res => {
            $("#add-jobCtlTable").modal('hide');
            $('.modal-backdrop').remove();

            if (res.status === 200) {
                obj = JSON.parse(res.bodyText);

                if (obj.errorCode === "0000") {
                    jobCtlQuery();
                    layer.msg(obj.errorDesc, {icon: 1, time: 1000});
                } else {
                    layer.alert(obj.errorDesc, {icon: 2, time: 2000});
                }
            } else {
                layer.alert(res.bodyText, {icon: 2, time: 2000});
            }
        }, res => {
            layer.alert(res, {icon: 5, time: 20000});
        });
    }

    function jobCtlTableEdit() {
        let editParams = Object.assign({}, vmCtl.editJobCtlTable);

        editParams.execDay = getExecDayKey(editParams.execDay);
        editParams.execTimes = getExecTimesKey(editParams.execTimes);
        editParams.valid = getValidKey(editParams.valid);

        //console.log("edit:", editParams);

        Vue.http.put('{[{urlfor "JobCtlController.Put"}]}', editParams).then(res => {
            $("#edit-jobCtlTable").modal('hide');
            $('.modal-backdrop').remove();

            if (res.status === 200) {
                obj = JSON.parse(res.bodyText);

                if (obj.errorCode === "000") {
                    jobCtlQuery();
                    layer.msg(obj.errorDesc, {icon: 1, time: 1000});
                } else {
                    layer.alert(obj.errorDesc, {icon: 2, time: 2000});
                }
            } else {
                layer.alert(res.bodyText, {icon: 2, time: 2000});
            }
        }, res => {
            layer.alert(res, {icon: 5, time: 20000});
        });
    }

    function jobCtlTableDelete(index) {
        Vue.http.delete('{[{urlfor "JobCtlController.Delete"}]}', {params: {jobId: vmCtl.deleteJobCtlTable.jobId}}).then(res => {
            $("#delete-jobCtlTable").modal('hide');
            $('.modal-backdrop').remove();

            if (res.status === 200) {
                obj = JSON.parse(res.bodyText);

                if (obj.errorCode === "000") {
                    jobCtlQuery();
                    layer.msg(obj.errorDesc, {icon: 1, time: 1000});
                } else {
                    layer.alert(obj.errorDesc, {icon: 2, time: 2000});
                }
            } else {
                layer.alert(res.bodyText, {icon: 2, time: 2000});
            }
        }, res => {
            layer.alert(res, {icon: 5, time: 20000});
        });
    }

    function jobCtlTableRun(index) {
        Vue.http.post('{[{urlfor "JobSingleExec.Post"}]}', {jobId: vmCtl.runJobCtlTable.jobId}).then(res => {
            $("#run-jobCtlTable").modal('hide');
            $('.modal-backdrop').remove();

            if (res.status === 200) {
                obj = JSON.parse(res.bodyText);

                if (obj.errorCode === "000") {
                    layer.msg(obj.errorDesc, {icon: 1, time: 1000});
                } else {
                    layer.alert(obj.errorDesc, {icon: 2, time: 2000});
                }
            } else {
                layer.alert(res.bodyText, {icon: 2, time: 2000});
            }
        }, res => {
            layer.alert(res, {icon: 5, time: 20000});
        });
    }

    function jobCtlDetail(index) {
        taskTableDetail(jobCtlTable.rows().data()[index], '500px');
    }

    function jobDtlDetail(index) {
        taskTableDetail(jobDtlTable.rows().data()[index], '650px');
    }

    function taskTableDetail(row, height) {
        let content = '<div class="table-responsive"><table class="table">';

        let tpl = '<tr><th style="width:30%;text-align:right">key : </th><td>value</td></tr>';

        Object.keys(row).forEach(function (key) {
            content += tpl.replace("key", fieldMap[key]).replace("value", getValueShow(key, row[key]));
        });

        content += '</table></div>';

        layer.open({
            type: 1,
            title: '记录明细',
            shadeClose: true,
            offset: 'auto',
            shade: 0.6,
            anim: 0,
            area: ['500px', height],
            zIndex: layer.zIndex,
            success: layero => layer.setTop(layero),
            content: content
        });
    }
</script>